本篇同步發文在個人Blog: 一袋.NET要扛幾樓?打造容器化的ASP.NET Core網站!系列文章 - (9) 建立商品列表的頁面 - 2
這些Model是從Web API取得Json後,再反序列化的目標。而這些Model建立在Models資料夾。
每個商品的資料細節定義在此類別
namespace WebMvc.Models
{
public class CatalogItem
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string PictureUrl { get; set; }
}
}
我們取商品列表是有分頁的功能,而Catalog包含分頁的資訊和CatalogItem列表
using System.Collections.Generic;
namespace WebMvc.Models
{
public class Catalog
{
public int PageIndex { get; set; }
public int PageSize { get; set; }
public int Count { get; set; }
public List<CatalogItem> Data { get; set; }
}
}
從Controller要對資料CRUD,都是透過服務(Service),於是在WebMvc新增Services資料夾。
包含取得商品類別列表與商品列表的2個方法
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebMvc.Models;
namespace WebMvc.Services
{
public interface ICatalogService
{
Task<Catalog> GetCatalogItems(int pageIndex, int pageSize, int? type);
Task<IEnumerable<SelectListItem>> GetTypes();
}
}
建立CatalogService,並注入前述自定義的IHttpClient、設定檔的IOptionsSnapshot。從設定檔的CatalogUrl取得商品服務的Url,再組成api的route,依照前述ApiPaths做Http查詢。返回的結果是Json字串,需用Newtonsoft.Json做反序列化。
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebMvc.Infrastructure;
using WebMvc.Models;
namespace WebMvc.Services
{
public class CatalogService : ICatalogService
{
private readonly IOptionsSnapshot<AppSettings> _settings;
private readonly IHttpClient _apiClient;
private readonly ILogger<CatalogService> _logger;
private readonly string _remoteServiceBaseUrl;
public CatalogService(
IOptionsSnapshot<AppSettings> settings,
IHttpClient httpClient,
ILogger<CatalogService> logger)
{
_settings = settings;
_apiClient = httpClient;
_logger = logger;
_remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/catalog/";
}
public async Task<Catalog> GetCatalogItems(int pageIndex, int pageSize, int? type)
{
var allcatalogItemsUri = ApiPaths.Catalog.GetAllCatalogItems(
_remoteServiceBaseUrl,
pageIndex,
pageSize,
type);
var dataString = await _apiClient.GetStringAsync(allcatalogItemsUri);
var response = JsonConvert.DeserializeObject<Catalog>(dataString);
return response;
}
public async Task<IEnumerable<SelectListItem>> GetTypes()
{
var getTypesUri = ApiPaths.Catalog.GetAllTypes(_remoteServiceBaseUrl);
var dataString = await _apiClient.GetStringAsync(getTypesUri);
var items = new List<SelectListItem>
{
new SelectListItem()
{
Value = null,
Text = "All",
Selected = true
}
};
var types = JArray.Parse(dataString);
foreach (var brand in types.Children<JObject>())
{
items.Add(new SelectListItem()
{
Value = brand.Value<string>("id"),
Text = brand.Value<string>("type")
});
}
return items;
}
}
}
在專案根目錄建立AppSettings.cs類別,並將設定檔的值對應到此類別的屬性
namespace WebMvc
{
public class AppSettings
{
public string CatalogUrl { get; set; }
}
}
需要註冊自定義的服務和設定檔,並將預設Route指到CatalogController
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration);
services.AddSingleton<IHttpClient, CustomHttpClient>();
services.AddTransient<ICatalogService, CatalogService>();
// other code...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// other code...
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Catalog}/{action=Index}/{id?}");
});
}
------------------------------------------
目前網頁排版還有些問題, 正在努力修改....
明天得PO上來阿~~~